FE-716: Chat runtime β unified chat surface with inline secondary chats#141
Draft
kostandinang wants to merge 11 commits into
Draft
FE-716: Chat runtime β unified chat surface with inline secondary chats#141kostandinang wants to merge 11 commits into
kostandinang wants to merge 11 commits into
Conversation
Promote chat-runtime-secondary-chats to Active in PLAN.md (Linear=FE-716) with V1 narrowing and deferred list. CARDS.md decomposes FE-716 into commit-sized slices C0βC10. Adopt 'secondary chat' lexicon throughout (matches PR #139). Retire HANDOFF.md per its contract. Co-authored-by: Amp <amp@ampcode.com>
Copy docs/design/UNIFIED_CHAT_UX.md verbatim from PR #138 as the in-tree UX ceiling. Body unedited per user directive; a prepended FE-716 reading note documents vocabulary (thread = secondary chat) and substrate (D153 defers a schema-level thread table; FE-716 uses chat columns + existing chat.kind). Co-authored-by: Amp <amp@ampcode.com>
Add nullable parent_chat_id, invoked_in_turn_id, pinned_item_id, pinned_span_hint to the chat table plus indexes on parent_chat_id and invoked_in_turn_id (migration 0020). Zero enum changes β chat.kind stays ['interview', 'side_chat']. Tests cover column shape, index presence, FK rejection, and active_turn_id preservation. Co-authored-by: Amp <amp@ampcode.com>
createSecondaryChat inserts a chat row with kind='side_chat' and the four C1 columns. createKickoffTurn inserts a turn with turn_kind='kickoff' and resolves specification_id from the chat. POST route deferred to C3 (no client consumer yet). Tests cover happy paths, optional columns, and FK rejection. Co-authored-by: Amp <amp@ampcode.com>
listSecondaryChatsForSpecification returns chat rows where parent_chat_id IS NOT NULL with their earliest kickoff turn. readSpecificationStateProjection includes a new secondaryChats field; secondaryChatStateSchema added to api-types.ts (additive). Tests cover empty, single-with-kickoff, missing-kickoff, primary-chat exclusion, multi-spec scoping, and bundle round-trip. Co-authored-by: Amp <amp@ampcode.com>
Radix Collapsible-backed surface keyed off the secondaryChats wire shape. Header always renders; body collapsed by default and reveals the kickoff turn's assistant_parts on expand; tolerates kickoffTurn=null. Mounting in the workspace view is deferred to C3c-mount. Tests cover header render, default collapsed, expand on click, and empty body fallback. Co-authored-by: Amp <amp@ampcode.com>
handleCreateSecondaryChatRequest validates spec + body (parentChatId,
invokedInTurnId, itemKind, itemId, spanHint?), resolves the item via
getKnowledgeItem (rejects when missing or kind/spec mismatch), then
calls createSecondaryChat + createKickoffTurn and returns {chatId,
kickoffTurnId}. Existing POST /side-chat untouched (deletion is C8).
Per-mode kickoff templates land in C4. Tests cover happy path with
bundle round-trip, span-hint persistence, 400 on bad body, 404 on
missing spec, 404 on missing item.
Co-authored-by: Amp <amp@ampcode.com>
β¦turn
Project specificationState.secondaryChats into a
secondaryChatsByInvokedTurnId map on ContinuousWorkspaceController and
thread it through ContinuousWorkspaceView into
WorkspaceTranscriptArtifacts. getArtifactAnchorTurnId covers all
turn-bearing artifact kinds. SecondaryChatCollapsible renders inline
under each matching anchor in a secondary-chats-for-turn-{id} slot;
chats without a matching artifact never render (no-orphan invariant).
Co-authored-by: Amp <amp@ampcode.com>
β¦button
SecondaryChatTriggerProvider derives parentChatId (= primary_chat_id)
and invokedInTurnId (= active_turn_id) from the spec bundle and exposes
create({kind, id}). useCreateSecondaryChatMutation POSTs to
/api/specifications/:id/secondary-chats and invalidates the bundle.
Mount the provider in the specification route. Add an 'Open inline
chat' button on the structured list-view ItemActionRail.
specificationSchema gains primary_chat_id?: number for transition.
Mode wiring follows in C4.
Co-authored-by: Amp <amp@ampcode.com>
Add nullable chat.mode column ('explore' | 'edit') via migration 0021.
createSecondaryChat defaults to 'explore'; setSecondaryChatMode rejects
non-secondary chats. Project mode through the bundle. Expose via PATCH
/api/specifications/:id/secondary-chats/:chatId/mode. Client adds
useSetSecondaryChatModeMutation; SecondaryChatCollapsible gets an
Ask/Edit toggle (sibling of CollapsibleTrigger to avoid nested
buttons); WorkspaceTranscriptArtifacts wires it via a thin
SecondaryChatCollapsibleWithMode wrapper. Streaming-with-tools wiring
deferred to C5. Update CARDS.md to mark C3c-mount, C3c-wire, C4 done.
Co-authored-by: Amp <amp@ampcode.com>
Contributor
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
b5e5c0e to
52ed431
Compare
C5 in CARDS.md is split into three sub-cards (server streaming β client composer + host β per-chat staging strip). Cross-cutting: Shape A partition seam adds producerChatId to PatchBase + a usePatchListForChat hook; reducer logic unchanged. Documents rejected alternatives (Shape B nested providers, Shape C map-of-lists, Shape D no-shared-abstraction) and order discipline (C5a β C5b β C5c sequential). Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019e2cd7-2c2f-70d7-9362-d17899d44ea5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stack context
Stacked on
ln/fe-709-reconciliations(PR #139). Part of the chat-runtime track that replaces the side-chat popover and other disconnected chat surfaces with one unified workspace chat where every secondary conversation (side, reconciliation, QA, strategy) renders inline as a collapsible secondary chat alongside the primary interview.What
V1 of inline secondary chats on the existing
chat/turnsubstrate (nothreadtable):chattable gainsparent_chat_id,invoked_in_turn_id,pinned_item_id,pinned_span_hint, andmode;createSecondaryChat+createKickoffTurnhelpers./api/specifications/:id/secondary-chatsand PATCH/.../secondary-chats/:chatId/mode.SecondaryChatCollapsible, collapsed by default, kickoff turn visible on expand.secondaryChatsByInvokedTurnId; transcript renders chats under their anchor turn (secondary-chats-for-turn-{id}slot) with no-orphan invariant.SecondaryChatTriggerProviderderives parent + anchor from the spec bundle;Open inline chatbutton on the structured list-view rail.chat.mode('explore' | 'edit'); inline toggle on the collapsible (read-only when noonSetMode); helper rejects non-secondary chats.Out of scope
#-mention knowledge-item injection (C6)chat.kindprojection (C7)SideChatPopoverretirement (C8)Verification
npm run verifygreen: 103 test files / 1317 tests pass; build clean.Draft β opening for visibility while C5βC10 land.